# -*- coding: utf-8 -*-
# @Author: Tim Liu
# @Date: 2024-05-29
# @Last Modified by: Tim Liu
# @Last Modified time: 2024-05-29

# @Description: api endpoints for Document crud

from fastapi import APIRouter, Depends, Security
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload

from utils.response import SuccessResponse

from crewplus.helper.verify import get_api_key
from crewplus.apps.apikey.models.account_api_key import AccountApiKey

from core.database import db_getter
from core.dependencies import IdList
from core.exception import CustomException

from utils import status
from . import schemas, cruds, params, models

app = APIRouter()


###########################################################
#    Document API
###########################################################
@app.get("/documents", summary="Get knowledge base document list")
async def get_documents(p: params.DocumentParams = Depends(), apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    model = models.DocumentDB
    options = [joinedload(model.create_user), joinedload(model.kbase)]
    schema = schemas.DocumentListOut
    datas, count = await cruds.DocumentDal(db).get_datas(
        **p.dict(),
        v_options=options,
        v_schema=schema,
        v_return_count=True
    )
    return SuccessResponse(datas, count=count)


@app.post("/document", summary="create one document")
async def create_document(data: schemas.Document, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    data.create_user_id = apikey.user_id
    
    return SuccessResponse(await cruds.DocumentDal(db).create_data(data=data))


@app.put("/document/{data_id}", summary="update one document detail")
async def change_document(data_id: int, data: schemas.Document, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
        
    return SuccessResponse(await cruds.DocumentDal(db).put_data(data_id, data))


@app.get("/document/{data_id}", summary="get one document detail by id")
async def get_document(data_id: int, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
          
    schema = schemas.DocumentSimpleOut
    return SuccessResponse(await cruds.DocumentDal(db).get_data(data_id, v_schema=schema))


@app.get("/document/add/view/number/{data_id}", summary="Add document's view number +1")
async def issue_add_view_number(data_id: int, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
        
    return SuccessResponse(await cruds.DocumentDal(db).add_view_number(data_id))


@app.delete("/documents", summary="batch delete documents", description="batch hard delete knowledge base documents from db")
async def delete_documents(ids: IdList = Depends(), apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    #TODO: check permission, account can only delete owned documents after login
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
        
    await cruds.DocumentDal(db).delete_datas(ids=ids.ids, v_soft=False)
    return SuccessResponse("Successfully deleted")
